package com.wdl.datarest.data;

import java.util.List;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;
import org.springframework.data.rest.core.annotation.RestResource;

import io.swagger.annotations.ApiOperation;

@RepositoryRestResource(path = "alarm")
public interface AlarmRepository extends PagingAndSortingRepository<Alarm, Long> {
    @RestResource(path="id")
    List<Alarm> findById(@Param("id") long id);

    @ApiOperation(value="Get all alarms for a peson specified with his ID")
    @RestResource(path="personId")
    List<Alarm> findByPersonId(@Param("personId") long personId);

    @Query(value = "select * from alarm where id = ?1 limit 1", nativeQuery = true)
    Alarm findByIndex(long index);

    @RestResource(path="all")
    Page<Alarm> findByInstitutionId(@Param("institutionId") long institutionId, Pageable p);

    @ApiOperation(value="Get all alarms for an institution")
    @RestResource(path="allList")
    List<Alarm> findByInstitutionId(@Param("institutionId") long institutionId);

    @RestResource(path="allStartTime")
    Page<Alarm> findByInstitutionIdAndRaisedTimeGreaterThan(@Param("institutionId") long institutionId, @Param("startTime") long startTime, Pageable p);

    @ApiOperation(value="Get all alarms that were raised after the time specified by startTime in ms for an institution")
    @RestResource(path="allStartTimeList")
    List<Alarm> findByInstitutionIdAndRaisedTimeGreaterThan(@Param("institutionId") long institutionId, @Param("startTime") long startTime);

    @RestResource(path="allEndTime")
    Page<Alarm> findByInstitutionIdAndRaisedTimeLessThan(@Param("institutionId") long institutionId, @Param("endTime") long endTime, Pageable p);

    @ApiOperation(value="Get all alarms that were raised before the time specified by endTime in ms for an institution")
    @RestResource(path="allEndTimeList")
    List<Alarm> findByInstitutionIdAndRaisedTimeLessThan(@Param("institutionId") long institutionId, @Param("endTime") long endTime);

    @RestResource(path="allStartTimeEndTime")
    Page<Alarm> findByInstitutionIdAndRaisedTimeGreaterThanAndRaisedTimeLessThan(@Param("institutionId") long institutionId, @Param("startTime") long startDate, @Param("endTime") long endDate, Pageable p);

    @ApiOperation(value="Get all alarms that were raised between the time specified by startTime and endTime in ms for an institution")
    @RestResource(path="allStartTimeEndTimeList")
    List<Alarm> findByInstitutionIdAndRaisedTimeGreaterThanAndRaisedTimeLessThan(@Param("institutionId") long institutionId, @Param("startTime") long startDate, @Param("endTime") long endDate);

    @RestResource(path="name")
    Page<Alarm> findByInstitutionIdAndPersonNameContainsIgnoringCase(@Param("institutionId") long institutionId, @Param("personName") String personName, Pageable p);

    @ApiOperation(value="Get all alarms for a peson with his partial name for an institution")
    @RestResource(path="nameList")
    List<Alarm> findByInstitutionIdAndPersonNameContainsIgnoringCase(@Param("institutionId") long institutionId, @Param("personName") String personName);

    @RestResource(path="nameStartTime")
    Page<Alarm> findByInstitutionIdAndPersonNameContainsIgnoringCaseAndRaisedTimeGreaterThan(@Param("institutionId") long institutionId, @Param("personName") String personName, @Param("startTime") long startTime, Pageable p);

    @ApiOperation(value="Get all alarms that were raised after the time specified by startTime in ms for a peson with his partial name for an institution")
    @RestResource(path="nameStartTimeList")
    List<Alarm> findByInstitutionIdAndPersonNameContainsIgnoringCaseAndRaisedTimeGreaterThan(@Param("institutionId") long institutionId, @Param("personName") String personName, @Param("startTime") long startTime);

    @RestResource(path="nameEndTime")
    Page<Alarm> findByInstitutionIdAndPersonNameContainsIgnoringCaseAndRaisedTimeLessThan(@Param("institutionId") long institutionId, @Param("personName") String personName, @Param("endTime") long endTime, Pageable p);

    @ApiOperation(value="Get all alarms that were raised before the time specified by endTime in ms for a peson with his partial name for an institution")
    @RestResource(path="nameEndTimeList")
    List<Alarm> findByInstitutionIdAndPersonNameContainsIgnoringCaseAndRaisedTimeLessThan(@Param("institutionId") long institutionId, @Param("personName") String personName, @Param("endTime") long endTime);

    @RestResource(path="nameStartTimeEndTime")
    Page<Alarm> findByInstitutionIdAndPersonNameContainsIgnoringCaseAndRaisedTimeGreaterThanAndRaisedTimeLessThan(@Param("institutionId") long institutionId, @Param("personName") String personName, @Param("startTime") long startTime, @Param("endTime") long endDate, Pageable p);

    @ApiOperation(value="Get all alarms that were raised between the time specified by startTime and endTime in ms for a peson with his partial name for an institution")
    @RestResource(path="nameStartTimeEndTimeList")
    List<Alarm> findByInstitutionIdAndPersonNameContainsIgnoringCaseAndRaisedTimeGreaterThanAndRaisedTimeLessThan(@Param("institutionId") long institutionId, @Param("personName") String personName, @Param("startTime") long startTime, @Param("endTime") long endDate);

    @RestResource(path="firstUnackAlarmType")
    @Query(value = "select * from alarm where institution_id = ?1 and person_id = ?2 and acked_time = 0 and type = ?3 order by raised_time desc limit 1", nativeQuery = true)
    List<Alarm> findUnackAlarmByPersonIdAndType(@Param("institutionId") long institutionId, @Param("personId") long personId, @Param("alarm") String alarm);	

    @Query(value = "select * from alarm where person_id = ?1 and acked_time = 0 and (type = ?2 or type = ?3 or type = ?4 )", nativeQuery = true)
    List<Alarm> findUnackBedAlarmByPersonId(long personId, int upType, int sideType, int awayType);

    @Query(value = "select * from alarm where person_id = ?1 and acked_time = 0 and type = ?2 ", nativeQuery = true)
    List<Alarm> findUnackAlarmByPersonIdAndType(long personId, int alarmType);

    @ApiOperation(value="Get all alarms for a specific type that were raised after the time specified by \"from\" in ms for a peson with his ID")
    @RestResource(path="findAlarmTypeAfter")
    @Query(value = "select * from alarm where institution_id = ?1 and person_id = ?2 and raised_time > ?4 and type = ?3 order by raised_time desc", nativeQuery = true)
    List<Alarm> findAlarmTypeAfter(@Param("institutionId") long institutionId, @Param("personId") long personId, @Param("alarm") String alarm, @Param("from") long from);	

    // alarm is in integer value
    @ApiOperation(value="Get total alarm number for a specific type that were raised after the time specified by \"from\" in ms for a peson with his ID")
    @RestResource(path="countAlarmTypeAfter")
    @Query(value = "select count(*) from alarm where person_id = ?1 and raised_time > ?3 and type = ?2", nativeQuery = true)
    long countAlarmTypeAfter(@Param("personId") long personId, @Param("alarm") String alarm, @Param("from") long from);	

    // Doesn't seem to be used!!
    @RestResource(path="findAlarmTypeFromTo")
    @Query(value = "select * from alarm where institution_id = ?1 and person_id = ?2 and raised_time > ?4 and raised_time < ?5 and type = ?3 order by raised_time desc", nativeQuery = true)
    List<Alarm> findAlarmTypeFromTo(@Param("institutionId") long institutionId, @Param("personId") long personId, @Param("alarm") String alarm, @Param("from") long from, @Param("to") long to);	
}